/* Copyright (c) 2008 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package sample.blogger;

import java.io.Console;
import java.io.IOException;
import java.net.URL;
import java.util.Date;
import java.util.StringTokenizer;

import sample.util.SimpleCommandLineParser;

import com.google.gdata.client.Query;
import com.google.gdata.client.blogger.BloggerService;
import com.google.gdata.data.DateTime;
import com.google.gdata.data.Entry;
import com.google.gdata.data.Feed;
import com.google.gdata.util.ServiceException;

public class BloggerClient {

	private static final String METAFEED_URL = "http://www.blogger.com/feeds/default/blogs";

	private static final String FEED_URI_BASE = "http://www.blogger.com/feeds";
	private static final String POSTS_FEED_URI_SUFFIX = "/posts/default";

	private String[] feedUri;

	private BloggerClient() {
	}

	private static String[] getBlogIds(BloggerService myService)
			throws ServiceException, IOException {
		// Get the metafeed
		final URL feedUrl = new URL(METAFEED_URL);
		Feed resultFeed = myService.getFeed(feedUrl, Feed.class);

		// If the user has a blog then return the id (which comes after 'blog-')
		String[] forReturn;
		if (resultFeed.getEntries().size() > 0) {
			forReturn = new String[resultFeed.getEntries().size()];
			int index = 0;
			for (Entry myEntry : resultFeed.getEntries()) {
				forReturn[index++] = myEntry.getId().split("blog-")[1];
			}

			return forReturn;
		}
		throw new IOException("User has no blogs!");
	}

	public static void printUserBlogs(BloggerService myService)
			throws ServiceException, IOException {

		// Request the feed
		final URL feedUrl = new URL(METAFEED_URL);
		Feed resultFeed = myService.getFeed(feedUrl, Feed.class);

		// Print the results
		System.out.println(resultFeed.getTitle().getPlainText());
		for (int i = 0; i < resultFeed.getEntries().size(); i++) {
			Entry entry = resultFeed.getEntries().get(i);
			System.out.println("\t" + entry.getTitle().getPlainText());
		}
		System.out.println();
	}

	/**
	 * Displays the titles of all the posts in a blog. First it requests the
	 * posts feed for the blogs and then is prints the results.
	 * 
	 * @param myService
	 *            An authenticated GoogleService object.
	 * @throws ServiceException
	 *             If the service is unable to handle the request.
	 * @throws IOException
	 *             If the URL is malformed.
	 */
	public void printAllPosts(BloggerService myService)
			throws ServiceException, IOException {
		// Request the feed
		for (String feedUriEntry : feedUri) {
			URL feedUrl = new URL(feedUriEntry + POSTS_FEED_URI_SUFFIX);
			Feed resultFeed = myService.getFeed(feedUrl, Feed.class);

			// Print the results
			System.out.println(resultFeed.getTitle().getPlainText());
			for (int i = 0; i < resultFeed.getEntries().size(); i++) {
				Entry entry = resultFeed.getEntries().get(i);
				System.out.println("\t" + entry.getTitle().getPlainText());
			}
			System.out.println();
		}
	}

	/**
	 * Displays the title and modification time for any posts that have been
	 * created or updated in the period between the startTime and endTime
	 * parameters. The method creates the query, submits it to the
	 * GoogleService, then displays the results.
	 * 
	 * Note that while the startTime is inclusive, the endTime is exclusive, so
	 * specifying an endTime of '2007-7-1' will include those posts up until
	 * 2007-6-30 11:59:59PM.
	 * 
	 * @param myService
	 *            An authenticated GoogleService object.
	 * @param startTime
	 *            DateTime object specifying the beginning of the search period
	 *            (inclusive).
	 * @param endTime
	 *            DateTime object specifying the end of the search period
	 *            (exclusive).
	 * @throws ServiceException
	 *             If the service is unable to handle the request.
	 * @throws IOException
	 *             If the URL is malformed.
	 */
	public void printDateRangeQueryResults(BloggerService myService,
			DateTime startTime, DateTime endTime) throws ServiceException,
			IOException {
		// Create query and submit a request
		int wordCount = 0;

		for (String feedUriEntry : feedUri) {
			URL feedUrl = new URL(feedUriEntry + POSTS_FEED_URI_SUFFIX);
			Query myQuery = new Query(feedUrl);
			myQuery.setPublishedMin(startTime);
			myQuery.setPublishedMax(endTime);
			Feed resultFeed = myService.query(myQuery, Feed.class);

			// Print the results
			if (resultFeed.getEntries().size() > 0) {
				System.out.println(resultFeed.getTitle().getPlainText()
						+ " posts between " + startTime + " and " + endTime);
				for (int i = 0; i < resultFeed.getEntries().size(); i++) {
					Entry entry = resultFeed.getEntries().get(i);
					System.out.println("\t" + entry.getTitle().getPlainText());
					System.out.println("\t"
							+ entry.getUpdated().toStringRfc822());

					String content = entry.getTextContent().getContent()
							.getPlainText();
					StringTokenizer st = new StringTokenizer(content, " ");
					int count = st.countTokens();
					System.out.println("Number of words is: " + count);
					wordCount += count;

				}
				System.out.println();
			}
		}
		System.out.println("Total words added in the last 24 hours: "
				+ wordCount);
	}

	/**
	 * Runs through all the examples using the given GoogleService instance.
	 * 
	 * @param myService
	 *            An authenticated GoogleService object.
	 * @param userName
	 *            username of user to authenticate (e.g. jdoe@gmail.com).
	 * @param userPassword
	 *            password to use for authentication.
	 * @throws ServiceException
	 *             If the service is unable to handle the request.
	 * @throws IOException
	 *             If there is an error communicating with the server.
	 */
	public void run(BloggerService myService, String userName,
			String userPassword) throws ServiceException, IOException {
//
		myService.setUserCredentials(userName, userPassword);

		String[] blogId = getBlogIds(myService);
		feedUri = new String[blogId.length];

		for (int i = 0; i < blogId.length; i++) {
			feedUri[i] = FEED_URI_BASE + "/" + blogId[i];
		}

		// printUserBlogs(myService);
		// printAllPosts(myService);
		Date since = null;
		try {
			since = DateFactory.advance(new Date(), -1);
		} catch (Exception e) {
			throw new IOException("Date did not parse correctly");
		}
		printDateRangeQueryResults(myService, new DateTime(since),
				DateTime.now());

	}

	/**
	 * Uses the command line arguments to authenticate the GoogleService and
	 * build the basic feed URI, then invokes all the other methods to
	 * demonstrate how to interface with the Blogger service.
	 * 
	 * @param args
	 *            See the usage method.
	 */
	public static void main(String[] args) {

		 Console c = System.console();
		 if (c == null) {
		 System.err.println("No console.");
		 System.exit(1);
		 }

		 String userName = c.readLine("Enter your login: ");
		 char[] charPassword = c.readPassword("Enter your password: ");
		 String userPassword = new String(charPassword);

		// Set username, password and feed URI from command-line arguments.
		SimpleCommandLineParser parser = new SimpleCommandLineParser(args);
		// String userName = parser.getValue("username", "user", "u");
		// String userPassword = parser.getValue("password", "pass", "p");
		boolean help = parser.containsKey("help", "h");
		if (help || (userName == null) || (userPassword == null)) {
			usage();
			System.exit(1);
		}

		BloggerService myService = new BloggerService("exampleCo-exampleApp-1");

		try {
			BloggerClient bc = new BloggerClient();

			bc.run(myService, userName, userPassword);
		} catch (ServiceException se) {
			se.printStackTrace();
		} catch (IOException ioe) {
			ioe.printStackTrace();
		}
	}

	/**
	 * Prints the command line usage of this sample application.
	 */
	private static void usage() {
		System.out.println("Usage: BloggerClient --username <username>"
				+ " --password <password>");
		System.out.println("\nA simple application that creates, queries,\n"
				+ "updates and deletes posts and comments on the\n"
				+ "specified blog using the provided username and\n"
				+ "password for authentication.");
	}
}
